/**
 * @file inputHandler.h
 * @brief Definisce l'interfaccia dell'InputHandler.
 *
 * Contiene la definizione delle strutture utilizzate per comunicare con l'InputHandler
 * e le funzioni dichiarate pubblicamente.
 *
 * @date Mar 14, 2012
 * @author Francesco Corvino
 */

#ifndef INPUTHANDLER_H_
#define INPUTHANDLER_H_

#include <stdbool.h>			/** si utilizzano gli operatori booleani */
#include <sys/time.h>			/** libreria necessaria per utilizzare la chiamata select() */
#include <sys/types.h>			/** libreria necessaria per utilizzare la chiamata select() */
#include <unistd.h>				/** libreria necessaria per utilizzare la chiamata select() */
#include <sys/select.h>			/** libreria necessaria per utilizzare la chiamata pselect() */
#include <signal.h>				/** per la gestione dei segnali */

#include "../MemObj/executionObj.h"		/** le strutture utilizzate richiedono questo oggetto di memoria */

#define LOG_INPUTHANDLER_NAME "InputHandler"

/**
 * @brief Struttura per definire le configurazioni dell'entità InputHandler.
 *
 */
typedef struct inputHandler {
	/**
	 * @brief indica se bisogna eseguire in loop l'attesa di un'input.
	 */
	char isLoop;

	/**
	 * @brief indica se successivamente le impostazioni possono essere riconfigurate.
	 */
	char isConfigurable;

	/**
	 * @brief indica quanto deve restare in attesa di un'input.
	 */
	struct timeval timeToWaitInput;

	/**
	 * @brief Indica i filtri presenti per le richieste
	 */
	DynArray requestfilters;

	/**
	 * @brief Maschera dei segnali che l'applicazione deve gestire.
	 */
	sigset_t setInputSignals;

	/**
	 * @brief Segnale utilizzato per aggiornare lo stato dell'input.
	 */
	int updateSignal;

} InputHandler;

/**
 * @brief utilizzata per specificare un filtro di analisi dell'input.
 *
 * La struttura dati si può sintetizzare come una coda a singolo scorrimento
 * (unico puntatore next) di puntatori a funzione.
 *
 * In particolare il puntatore a funzione deve essere necessariamente una funzione definita come:
 * <code>UserRequest* (*fn)(UserRequest*)</code> poichè i filtri verranno applicati in catena: il risultato
 * di uno sarà il parametro dell'altro.
 */
typedef struct inputFilter {
	UserRequest* (*filter)(UserRequest*);
} InputFilter;

//////////////////////////////////////////////////////////////////////////////////////////////////////
////// funzioni di gestione dell'InputHandler ////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * @brief permette di configurare l'InputHandler.
 *
 * @param config configurazioni da impostare.
 */
void IH_setConfiguration(InputHandler * config);

/**
 * @brief consente di aggiungere un filtro.
 *
 * @param filter filtro da aggiungere.
 */
void IH_addChainFilter(InputFilter * filter);

/**
 * @brief si mette in attesa di un'input.
 */
void IH_waitAnInput();

/**
 * @brief aggiorna lo stato dell'input.
 */
void IH_updateInput();

#endif /* INPUTHANDLER_H_ */
